home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / clients / bitmap / handlers.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-12  |  18.6 KB  |  675 lines

  1. /*
  2.  * $XConsortium: Handlers.c,v 1.10 91/07/24 15:25:01 converse Exp $
  3.  *
  4.  * Copyright 1989 Massachusetts Institute of Technology
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and its
  7.  * documentation for any purpose is hereby granted without fee, provided that
  8.  * the above copyright notice appear in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the name of M.I.T. not be used in advertising or
  11.  * publicity pertaining to distribution of the software without specific,
  12.  * written prior permission.  M.I.T. makes no representations about the
  13.  * suitability of this software for any purpose.  It is provided "as is"
  14.  * without express or implied warranty.
  15.  *
  16.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  17.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  18.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  21.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  *
  23.  * Author:  Davor Matic, MIT X Consortium
  24.  */
  25.  
  26. #include <X11/StringDefs.h>
  27. #ifdef MSDOS
  28. #include "X11/IntrinsP.h"      /* QDK 05/11/1994 10:44am. */
  29. #else
  30. #include "X11/IntrinsicP.h"
  31. #endif
  32. #include "BitmapP.h"
  33.     
  34. #include <stdio.h>
  35. #include <string.h>
  36. #include <math.h>
  37.  
  38. #ifndef abs
  39. #define abs(x)                        (((int)(x) > 0) ? (x) : -(x))
  40. #endif
  41. #define min(x, y)                     (((int)(x) < (int)(y)) ? (x) : (y))
  42. #define max(x, y)                     (((int)(x) > (int)(y)) ? (x) : (y))
  43.  
  44. #include "Requests.h"
  45.  
  46. extern Boolean DEBUG;
  47.  
  48. /*****************************************************************************
  49.  *                                  Handlers                                 *
  50.  *****************************************************************************/
  51.  
  52. #define QueryInSquare(BW, x, y, square_x, square_y)\
  53.     ((InBitmapX(BW, x) == (square_x)) &&\
  54.      (InBitmapY(BW, y) == (square_y)))
  55.  
  56.  
  57. void DragOnePointHandler(w, client_data, event, cont) /* ARGSUSED */
  58.      Widget       w;
  59.      XtPointer    client_data;
  60.      XEvent      *event;
  61.      Boolean     *cont;
  62. {
  63.     BWStatus *status = (BWStatus *)client_data;
  64.     BitmapWidget BW = (BitmapWidget) w;
  65.  
  66.     if (DEBUG)
  67.     fprintf(stderr, "D1PH ");
  68.  
  69.     switch (event->type) {
  70.     
  71.     case ButtonPress:
  72.     if (event->xbutton.state != status->state) return;
  73.     if (!QuerySet(status->at_x, status->at_y)) {
  74.         BWStoreToBuffer(w);
  75.         status->value = Value(BW, event->xbutton.button);
  76.         status->btime = event->xbutton.time;
  77.         status->at_x = InBitmapX(BW, event->xbutton.x);
  78.         status->at_y = InBitmapY(BW, event->xbutton.y);
  79.         status->success = (Boolean) status->draw;
  80.         if (status->draw)
  81.         (*status->draw)(w,
  82.                 status->at_x, status->at_y, status->value);
  83.     }
  84.     break;
  85.     
  86.     case ButtonRelease:
  87.     if (QuerySet(status->at_x, status->at_y)) {
  88.         status->value = Value(BW, event->xbutton.button);
  89.         status->btime = event->xbutton.time;
  90.         status->at_x = InBitmapX(BW, event->xbutton.x);
  91.         status->at_y = InBitmapY(BW, event->xbutton.y);
  92.         status->success = (Boolean) status->draw;
  93.         /* SUPPRESS 701 */
  94.         BWTerminateRequest(w, TRUE); 
  95.     }
  96.     break;
  97.  
  98.     case MotionNotify:
  99.     if (QuerySet(status->at_x, status->at_y)) {
  100.         if (!QueryInSquare(BW, event->xmotion.x, event->xmotion.y,
  101.                    status->at_x, status->at_y)) {
  102.         status->at_x = InBitmapX(BW, event->xmotion.x);
  103.         status->at_y = InBitmapY(BW, event->xmotion.y);
  104.         if (status->draw)
  105.             (*status->draw)(w,
  106.                     status->at_x, status->at_y, status->value);
  107.         }
  108.     }
  109.     break;
  110.  
  111.     }
  112. }
  113.  
  114. void DragOnePointEngage(w, status, draw, state)
  115.     Widget      w;
  116.     BWStatus   *status;
  117.     void      (*draw)();
  118.     int        *state;
  119. {
  120.     
  121.     status->at_x = NotSet;
  122.     status->at_y = NotSet;
  123.     status->draw = draw;
  124.     status->success = False;
  125.     status->state = *state;
  126.     
  127.     XtAddEventHandler(w,
  128.               ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
  129.               FALSE, DragOnePointHandler, (XtPointer)status);
  130. }
  131.  
  132. /* ARGSUSED */
  133. void DragOnePointTerminate(w, status, client_data)
  134.     Widget     w;
  135.     BWStatus  *status;
  136.     caddr_t    client_data;
  137. {
  138.     
  139.     if (status->success) {
  140.     BWChangeNotify(w, NULL, NULL);
  141.     BWSetChanged(w);
  142.     }
  143.     
  144.     XtRemoveEventHandler(w,
  145.          ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
  146.          FALSE, DragOnePointHandler, (XtPointer)status);
  147.     
  148. }
  149.  
  150. void OnePointHandler(w, client_data, event, cont) /* ARGSUSED */
  151.     Widget       w;
  152.     XtPointer    client_data;
  153.     XEvent      *event;
  154.     Boolean     *cont;
  155. {
  156.     BWStatus    *status = (BWStatus *)client_data;
  157.     BitmapWidget BW = (BitmapWidget) w;
  158.     
  159.     if (DEBUG)
  160.     fprintf(stderr, "1PH ");
  161.  
  162.     switch (event->type) {
  163.     
  164.     case Expose:
  165.     if (QuerySet(status->at_x, status->at_y)) {
  166.         BWClip(w, event->xexpose.x, event->xexpose.y,
  167.            event->xexpose.width, event->xexpose.height);
  168.         if (status->draw)
  169.         (*status->draw)(w,
  170.                 status->at_x, status->at_y, Highlight);
  171.         
  172.         BWUnclip(w);
  173.     }
  174.     break;
  175.     
  176.     case ButtonPress:
  177.     if (event->xbutton.state != status->state) return;
  178.     if (!QuerySet(status->at_x, status->at_y)) {
  179.         status->value = Value(BW, event->xbutton.button);
  180.         status->btime = event->xbutton.time;
  181.         status->at_x = InBitmapX(BW, event->xbutton.x);
  182.         status->at_y = InBitmapY(BW, event->xbutton.y);
  183.         if (status->draw)
  184.         (*status->draw)(w,
  185.                 status->at_x, status->at_y, Highlight);
  186.     }
  187.     break;
  188.     
  189.     case ButtonRelease:
  190.     if (QuerySet(status->at_x, status->at_y)) {
  191.         if (status->draw)
  192.         (*status->draw)(w,
  193.                 status->at_x, status->at_y, Highlight);
  194.         
  195.         status->value = Value(BW, event->xbutton.button);
  196.         status->btime = event->xbutton.time;
  197.         status->at_x = InBitmapX(BW, event->xbutton.x);
  198.         status->at_y = InBitmapY(BW, event->xbutton.y);
  199.         status->success = True;
  200.         
  201.         BWTerminateRequest(w, TRUE);
  202.     }
  203.     break;
  204.     
  205.     case MotionNotify:
  206.     if (QuerySet(status->at_x, status->at_y)) {
  207.         if (!QueryInSquare(BW, event->xmotion.x, event->xmotion.y,
  208.                    status->at_x, status->at_y)) {
  209.         if (status->draw)
  210.             (*status->draw)(w,
  211.                     status->at_x, status->at_y, Highlight);
  212.         status->at_x = InBitmapX(BW, event->xmotion.x);
  213.         status->at_y = InBitmapY(BW, event->xmotion.y);
  214.         if (status->draw)
  215.             (*status->draw)(w,
  216.                     status->at_x, status->at_y, Highlight);
  217.         }
  218.     }      
  219.     break;
  220.     }
  221. }
  222.  
  223. void OnePointEngage(w, status, draw, state)
  224.     Widget      w;
  225.     BWStatus   *status;
  226.     void      (*draw)();
  227.     int        *state;
  228. {
  229.     status->at_x = NotSet;
  230.     status->at_y = NotSet;
  231.     status->draw = draw;
  232.     status->success = False;
  233.     status->state = *state;
  234.  
  235.     XtAddEventHandler(w,
  236.               ButtonPressMask | ButtonReleaseMask | 
  237.               ExposureMask | PointerMotionMask,
  238.               FALSE, OnePointHandler, (XtPointer)status);
  239. }
  240.  
  241. void OnePointImmediateEngage(w, status, draw, state)
  242.     Widget      w;
  243.     BWStatus   *status;
  244.     void      (*draw)();
  245.     int        *state;
  246. {
  247.     status->at_x = 0;
  248.     status->at_y = 0;
  249.     status->draw = draw;
  250.     status->success = False;
  251.     status->state = *state;
  252.     
  253.     if (status->draw)
  254.     (*status->draw)(w,
  255.             status->at_x, status->at_y, Highlight);
  256.     
  257.     XtAddEventHandler(w,
  258.               ButtonPressMask | ButtonReleaseMask | 
  259.               ExposureMask | PointerMotionMask,
  260.               FALSE, OnePointHandler, (XtPointer)status);
  261. }
  262.  
  263. void OnePointTerminate(w, status, draw)
  264.     Widget     w;
  265.     BWStatus  *status;
  266.     void     (*draw)();
  267. {
  268.     
  269.     if (status->success && draw) {
  270.     BWStoreToBuffer(w);
  271.     (*draw)(w,
  272.         status->at_x, status->at_y,
  273.         status->value);
  274.     BWChangeNotify(w, NULL, NULL);
  275.     BWSetChanged(w);
  276.     }    
  277.     else
  278.     if (QuerySet(status->at_x, status->at_y))
  279.         if (status->draw)
  280.         (*status->draw)(w,
  281.                 status->at_x, status->at_y, Highlight);
  282.     
  283.     XtRemoveEventHandler(w,
  284.              ButtonPressMask | ButtonReleaseMask | 
  285.              ExposureMask | PointerMotionMask,
  286.              FALSE, OnePointHandler, (XtPointer)status);
  287. }
  288.  
  289. void OnePointTerminateTransparent(w, status, draw)
  290.     Widget     w;
  291.     BWStatus  *status;
  292.     void     (*draw)();
  293. {
  294.     
  295.     if (status->success && draw)
  296.     (*draw)(w,
  297.         status->at_x, status->at_y,
  298.         status->value);
  299.     else
  300.     if (QuerySet(status->at_x, status->at_y))
  301.         if (status->draw)
  302.         (*status->draw)(w,
  303.                 status->at_x, status->at_y, Highlight);
  304.     
  305.     XtRemoveEventHandler(w,
  306.              ButtonPressMask | ButtonReleaseMask | 
  307.              ExposureMask | PointerMotionMask,
  308.              FALSE, OnePointHandler, (XtPointer)status);
  309.     
  310. }
  311.  
  312.  
  313. void TwoPointsHandler(w, client_data, event, cont) /* ARGSUSED */
  314.     Widget      w;
  315.     XtPointer  client_data;
  316.     XEvent     *event;
  317.     Boolean    *cont;
  318. {
  319.     BitmapWidget BW = (BitmapWidget) w;
  320.     BWStatus   *status = (BWStatus *)client_data;
  321.     if (DEBUG)
  322.     fprintf(stderr, "2PH ");
  323.     
  324.     switch (event->type) {
  325.     
  326.     case Expose:
  327.     if (QuerySet(status->from_x, status->from_y) && 
  328.         QuerySet(status->to_x, status->to_y)) {
  329.         BWClip(w, event->xexpose.x, event->xexpose.y,
  330.            event->xexpose.width, event->xexpose.height);
  331.         if (status->draw)
  332.         (*status->draw)(w,
  333.                 status->from_x, status->from_y, 
  334.                 status->to_x, status->to_y, Highlight);
  335.         BWUnclip(w);
  336.     }
  337.     break;
  338.     
  339.     case ButtonPress:
  340.     if (event->xbutton.state != status->state) return;
  341.     if (!QuerySet(status->from_x, status->from_y)) {
  342.         status->value = Value(BW, event->xbutton.button);
  343.         status->btime = event->xbutton.time;
  344.         status->from_x = InBitmapX(BW, event->xbutton.x);
  345.         status->from_y = InBitmapY(BW, event->xbutton.y);
  346.         status->to_x = InBitmapX(BW, event->xbutton.x);
  347.         status->to_y = InBitmapY(BW, event->xbutton.y);
  348.         if (status->draw)
  349.         (*status->draw)(w,
  350.                 status->from_x, status->from_y, 
  351.                 status->to_x, status->to_y, Highlight);
  352.     }
  353.     break;
  354.     
  355.     case ButtonRelease:
  356.     if (QuerySet(status->from_x, status->from_y)) {
  357.         if (status->draw)
  358.         (*status->draw)(w,
  359.                 status->from_x, status->from_y, 
  360.                 status->to_x, status->to_y, Highlight);
  361.         status->value = Value(BW, event->xbutton.button);
  362.         status->btime = event->xbutton.time;        
  363.         status->to_x = InBitmapX(BW, event->xbutton.x);
  364.         status->to_y = InBitmapY(BW, event->xbutton.y);
  365.         status->success = True;
  366.         
  367.         BWTerminateRequest(w, TRUE);
  368.     }
  369.     break;
  370.     
  371.     case MotionNotify:
  372.     if (QuerySet(status->from_x, status->from_y)) {
  373.         if (QuerySet(status->to_x, status->to_y)) {
  374.         if (!QueryInSquare(BW, event->xmotion.x, event->xmotion.y,
  375.                    status->to_x, status->to_y)) {
  376.             if (status->draw)
  377.             (*status->draw)(w,
  378.                     status->from_x, status->from_y, 
  379.                     status->to_x, status->to_y, Highlight);
  380.             status->to_x = InBitmapX(BW, event->xmotion.x);
  381.             status->to_y = InBitmapY(BW, event->xmotion.y);
  382.             if (status->draw)
  383.             (*status->draw)(w,
  384.                     status->from_x, status->from_y, 
  385.                     status->to_x, status->to_y, Highlight);
  386.         }
  387.         }
  388.         else {
  389.         status->to_x = InBitmapX(BW, event->xmotion.x);
  390.         status->to_y = InBitmapY(BW, event->xmotion.y);
  391.         if (status->draw)
  392.             (*status->draw)(w,
  393.                     status->from_x, status->from_y, 
  394.                     status->to_x, status->to_y, Highlight);
  395.         }
  396.     }
  397.     break;
  398.     }
  399. }
  400.  
  401. void TwoPointsEngage(w, status, draw, state)
  402.     Widget     w;
  403.     BWStatus  *status;
  404.     void     (*draw)();
  405.     int       *state;
  406. {
  407.     
  408.     status->from_x = NotSet;
  409.     status->from_y = NotSet;
  410.     status->to_x = NotSet;
  411.     status->to_y = NotSet;
  412.     status->draw = draw;
  413.     status->success = False;
  414.     status->state = *state;
  415.  
  416.     XtAddEventHandler(w,
  417.               ButtonPressMask | ButtonReleaseMask | 
  418.               ExposureMask | PointerMotionMask,
  419.               FALSE, TwoPointsHandler, (XtPointer)status);
  420. }
  421.  
  422. void TwoPointsTerminate(w, status, draw)
  423.     Widget    w;
  424.     BWStatus *status;
  425.     void    (*draw)();
  426. {
  427.     
  428.     if (status->success && draw) {
  429.     BWStoreToBuffer(w);
  430.     (*draw)(w,
  431.         status->from_x, status->from_y,
  432.         status->to_x, status->to_y,
  433.         status->value);
  434.     BWChangeNotify(w, NULL, NULL);
  435.     BWSetChanged(w);
  436.     }
  437.     else
  438.     if (QuerySet(status->from_x, status->from_y) && 
  439.         QuerySet(status->to_x, status->to_y))
  440.         if (status->draw)
  441.         (*status->draw)(w,
  442.                 status->from_x, status->from_y, 
  443.                 status->to_x, status->to_y, Highlight);
  444.     
  445.     XtRemoveEventHandler(w,
  446.              ButtonPressMask | ButtonReleaseMask | 
  447.              ExposureMask | PointerMotionMask,
  448.              FALSE, TwoPointsHandler, (XtPointer)status);
  449. }
  450.  
  451. void TwoPointsTerminateTransparent(w, status, draw)
  452.     Widget    w;
  453.     BWStatus *status;
  454.     void    (*draw)();
  455. {
  456.     
  457.     if (status->success && draw)
  458.     (*draw)(w,
  459.         status->from_x, status->from_y,
  460.         status->to_x, status->to_y,
  461.         status->value);
  462.     else
  463.     if (QuerySet(status->from_x, status->from_y) && 
  464.         QuerySet(status->to_x, status->to_y))
  465.         if (status->draw)
  466.         (*status->draw)(w,
  467.                 status->from_x, status->from_y, 
  468.                 status->to_x, status->to_y, Highlight);
  469.     
  470.     XtRemoveEventHandler(w,
  471.              ButtonPressMask | ButtonReleaseMask | 
  472.              ExposureMask | PointerMotionMask,
  473.              FALSE, TwoPointsHandler, (XtPointer)status);
  474. }
  475.  
  476. void TwoPointsTerminateTimed(w, status, draw)
  477.     Widget    w;
  478.     BWStatus *status;
  479.     void    (*draw)();
  480. {
  481.     
  482.     if (status->success && draw)
  483.     (*draw)(w,
  484.         status->from_x, status->from_y,
  485.         status->to_x, status->to_y,
  486.         status->btime);
  487.     else
  488.     if (QuerySet(status->from_x, status->from_y) && 
  489.         QuerySet(status->to_x, status->to_y))
  490.         if (status->draw)
  491.         (*status->draw)(w,
  492.                 status->from_x, status->from_y, 
  493.                 status->to_x, status->to_y, Highlight);
  494.     
  495.     XtRemoveEventHandler(w,
  496.              ButtonPressMask | ButtonReleaseMask | 
  497.              ExposureMask | PointerMotionMask,
  498.              FALSE, TwoPointsHandler, (XtPointer)status);
  499. }
  500.  
  501. /* ARGSUSED */
  502. void Interface(w, status, action)
  503.     Widget     w;
  504.     caddr_t    status;
  505.     void     (*action)();
  506. {
  507.      (*action)(w);
  508. }
  509.  
  510. void Paste(w, at_x, at_y, value)
  511.     Widget    w;
  512.     Position  at_x, at_y;
  513.     int       value;
  514. {
  515.     BitmapWidget    BW = (BitmapWidget) w;
  516.     BWStatus       *my_status;
  517.     BWRequest       request;
  518.  
  519.     my_status = (BWStatus *) 
  520.     BW->bitmap.request_stack[BW->bitmap.current].status;
  521.  
  522.     my_status->draw = NULL;
  523.  
  524.    request = (BWRequest)
  525.    BW->bitmap.request_stack[BW->bitmap.current].request->terminate_client_data;
  526.     
  527.     BWTerminateRequest(w, FALSE);
  528.     
  529.     if ((at_x == max(BW->bitmap.mark.from_x, min(at_x, BW->bitmap.mark.to_x)))
  530.     &&
  531.       (at_y == max(BW->bitmap.mark.from_y, min(at_y, BW->bitmap.mark.to_y)))) {
  532.     
  533.     BWStatus *status;
  534.     
  535.     if (DEBUG)
  536.         fprintf(stderr, "Prepaste request: %s\n", request);
  537.     
  538.     BWEngageRequest(w, request, False, (char *)&(my_status->state), sizeof(int));
  539.     
  540.     status = (BWStatus *) 
  541.         BW->bitmap.request_stack[BW->bitmap.current].status;
  542.     
  543.     status->at_x = at_x;
  544.     status->at_y = at_y;
  545.     status->value = value;
  546.     (*status->draw) (w, at_x, at_y, Highlight);    
  547.     }
  548.     else {
  549.  
  550.     BWStatus *status;
  551.     
  552.       BWEngageRequest(w, MarkRequest, False, (char *)&(my_status->state), sizeof(int));
  553.     
  554.     status = (BWStatus *) 
  555.         BW->bitmap.request_stack[BW->bitmap.current].status;
  556.     
  557.     status->from_x = status->to_x = at_x;
  558.     status->from_y = status->to_y = at_y;
  559.     status->value = value;
  560.     (*status->draw) (w, at_x, at_y, at_x, at_y, Highlight);
  561.     }
  562. }
  563.  
  564.  
  565. void DragTwoPointsHandler(w, client_data, event, cont) /* ARGSUSED */
  566.     Widget      w;
  567.     XtPointer   client_data;
  568.     XEvent     *event;
  569.     Boolean    *cont;
  570. {
  571.     BitmapWidget BW = (BitmapWidget) w;
  572.     BWStatus   *status = (BWStatus *)client_data;
  573.  
  574.     if (DEBUG)
  575.     fprintf(stderr, "D2PH ");
  576.  
  577.     switch (event->type) {
  578.     
  579.     case ButtonPress:
  580.     if (event->xbutton.state != status->state) return;
  581.     if (!QuerySet(status->from_x, status->from_y)) {
  582.         BWStoreToBuffer(w);
  583.         status->value = Value(BW, event->xbutton.button);
  584.         status->btime = event->xbutton.time;
  585.         status->from_x = InBitmapX(BW, event->xbutton.x);
  586.         status->from_y = InBitmapY(BW, event->xbutton.y);
  587.         status->to_x = InBitmapX(BW, event->xbutton.x);
  588.         status->to_y = InBitmapY(BW, event->xbutton.y);
  589.         status->success = (Boolean) status->draw;
  590.         if (status->draw)
  591.         (*status->draw)(w,
  592.                 status->from_x, status->from_y, 
  593.                 status->to_x, status->to_y, status->value);
  594.     }
  595.     break;
  596.     
  597.     case ButtonRelease:
  598.     if (QuerySet(status->from_x, status->from_y)) {
  599.         status->value = Value(BW, event->xbutton.button);
  600.         status->btime = event->xbutton.time;        
  601.         status->from_x = status->to_x;
  602.         status->from_y = status->to_y;
  603.         status->to_x = InBitmapX(BW, event->xbutton.x);
  604.         status->to_y = InBitmapY(BW, event->xbutton.y);
  605.         status->success = True;
  606.         
  607.         BWTerminateRequest(w, TRUE);
  608.     }
  609.     break;
  610.     
  611.     case MotionNotify:
  612.     if (QuerySet(status->from_x, status->from_y)) {
  613.         if (QuerySet(status->to_x, status->to_y)) {
  614.         if (!QueryInSquare(BW, event->xmotion.x, event->xmotion.y,
  615.                    status->to_x, status->to_y)) {
  616.             status->from_x = status->to_x;
  617.             status->from_y = status->to_y;
  618.             status->to_x = InBitmapX(BW, event->xmotion.x);
  619.             status->to_y = InBitmapY(BW, event->xmotion.y);
  620.             if (status->draw)
  621.             (*status->draw)(w,
  622.                     status->from_x, status->from_y, 
  623.                     status->to_x, status->to_y, status->value);
  624.         }
  625.         }
  626.     }
  627.     break;
  628.     }
  629. }
  630.  
  631. void DragTwoPointsEngage(w, status, draw, state)
  632.     Widget     w;
  633.     BWStatus  *status;
  634.     void     (*draw)();
  635.     int       *state;
  636. {
  637.     
  638.     status->from_x = NotSet;
  639.     status->from_y = NotSet;
  640.     status->to_x = NotSet;
  641.     status->to_y = NotSet;
  642.     status->draw = draw;
  643.     status->success = False;
  644.     status->state = *state;
  645.  
  646.     XtAddEventHandler(w,
  647.               ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
  648.               FALSE, DragTwoPointsHandler, (XtPointer)status);
  649. }
  650.  
  651. void DragTwoPointsTerminate(w, status, draw)
  652.     Widget     w;
  653.     BWStatus  *status;
  654.     void     (*draw)();
  655. {
  656.     
  657.     if (status->success && draw) {
  658.     if ((status->from_x != status->to_x) 
  659.         || 
  660.         (status->from_y != status->to_y))
  661.         (*draw)(w,
  662.             status->from_x, status->from_y,
  663.             status->to_x, status->to_y,
  664.             status->value);
  665.     BWChangeNotify(w, NULL, NULL);
  666.     BWSetChanged(w);
  667.     }
  668.     
  669.     XtRemoveEventHandler(w,
  670.                  ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
  671.              FALSE, DragTwoPointsHandler, (XtPointer)status);
  672. }
  673.  
  674. /*****************************************************************************/
  675.